# +----------------------------------------------------------------------
# | ChatWork智能聊天办公系统
# +----------------------------------------------------------------------
# | 软件声明: 本系统并非自由软件,未经授权任何形式的商业使用均属非法。
# | 版权保护: 任何企业和个人不允许对程序代码以任何形式任何目的复制/分发。
# | 授权要求: 如有商业使用需求,请务必先与版权所有者取得联系并获得正式授权。
# +----------------------------------------------------------------------
# | Author: ChatWork Team <2474369941@qq.com>
# +----------------------------------------------------------------------
import time
from tortoise import fields
from kernels.model import DbModel
from common.enums.wallet import WalletEnum
from common.utils.tools import ToolsUtil


class UserModel(DbModel):
    id = fields.IntField(pk=True, unsigned=True, description="主键")
    group_id = fields.IntField(null=False, default=0, description="用户分组")
    sn = fields.CharField(null=False, max_length=20, default="", description="用户编号")
    account = fields.CharField(null=False, max_length=32, default="", description="用户账号")
    password = fields.CharField(null=False, max_length=32, default="", description="登录密码")
    nickname = fields.CharField(null=False, max_length=32, default="", description="用户名称")
    avatar = fields.CharField(null=False, max_length=200, default="", description="用户头像")
    salt = fields.CharField(null=False, max_length=32, default="", description="加密盐巴")
    gender = fields.IntField(null=False, default=0, description="用户性别")
    mobile = fields.CharField(null=False, max_length=20, default="", description="手机号码")
    email = fields.CharField(null=False, max_length=100, default="", description="电子邮箱")
    points = fields.IntField(null=False, default=0, description="剩余积分")
    mcp_num = fields.IntField(null=False, default=0, description="MCP库数")
    know_num = fields.IntField(null=False, default=0, description="知识库数")
    robot_num = fields.IntField(null=False, default=0, description="智能体数")
    train_num = fields.IntField(null=False, default=0, description="训练组数")
    last_login_ip = fields.CharField(null=False, max_length=100, default="", description="最后登录IP")
    last_login_time = fields.IntField(null=False, default=0, description="最后登录时间")
    is_disable = fields.SmallIntField(null=False, default=0, description="是否禁用: [0=否, 1=是]")
    is_delete = fields.SmallIntField(null=False, default=0, description="是否删除: [0=否, 1=是]")
    create_time = fields.IntField(null=False, default=0, description="创建时间")
    update_time = fields.IntField(null=False, default=0, description="更新时间")
    delete_time = fields.IntField(null=False, default=0, description="删除时间")

    class Meta:
        table_description = "用户管理表"
        table = DbModel.table_prefix("user")

    @classmethod
    async def queryUserDictsById(cls, ids: list, field: list = None) -> dict:
        """ 获取用户字典 """
        dicts = {}
        if ids:
            field = ["id", "sn", "nickname", "avatar", "mobile"] if not field else field
            users = await (cls.filter(id__in=list(set(ids))).all().values(*field))
            dicts = {item["id"]: item for item in users}
        return dicts


class UserAuthModel(DbModel):
    id = fields.IntField(pk=True, unsigned=True, description="主键")
    user_id = fields.IntField(null=False, default=0, description="用户ID")
    openid = fields.CharField(null=False, max_length=32, default="", description="openid")
    unionid = fields.CharField(null=False, max_length=32, default="", description="unionid")
    terminal = fields.IntField(null=False, default=0, description="客户端[1=微信小程序, 2=微信公众号, 3=安卓, 4=苹果]")
    create_time = fields.IntField(null=False, default=0, description="创建时间")
    update_time = fields.IntField(null=False, default=0, description="更新时间")

    class Meta:
        table_description = "用户授权表"
        table = DbModel.table_prefix("user_auth")


class UserGroupModel(DbModel):
    id = fields.IntField(pk=True, unsigned=True, description="主键")
    name = fields.CharField(null=False, max_length=30, default="", description="名称")
    remarks = fields.CharField(null=False, max_length=200, default="", description="备注")
    sort = fields.IntField(null=False, default=0, description="排序")
    is_delete = fields.SmallIntField(null=False, default=0, description="是否删除: [0=否, 1=是]")
    create_time = fields.IntField(null=False, default=0, description="创建时间")
    update_time = fields.IntField(null=False, default=0, description="更新时间")
    delete_time = fields.IntField(null=False, default=0, description="删除时间")

    class Meta:
        table_description = "用户分组表"
        table = DbModel.table_prefix("user_group")

    @classmethod
    async def queryGroupDictsById(cls, ids: list, field: list = None) -> dict:
        """ 获取分组字典 """
        dicts = {}
        if ids:
            field = ["id", "name"] if not field else field
            groups = await (cls.filter(id__in=list(set(ids))).all().values(*field))
            dicts = {item["id"]: item for item in groups}
        return dicts


class UserSubscribeModel(DbModel):
    id = fields.IntField(pk=True, unsigned=True, description="主键")
    user_id = fields.IntField(null=False, default=0, description="用户ID")
    pricing_id = fields.IntField(null=False, default=0, description="定价ID")
    package_id = fields.IntField(null=False, default=0, description="套餐ID")
    snapshot = fields.TextField(null=False, default="", description="快照信息")
    is_perpetual = fields.SmallIntField(null=False, default=0, description="永久会员: [0=否, 1=是]")
    is_delete = fields.SmallIntField(null=False, default=0, description="是否删除: [0=否, 1=是]")
    remain_time = fields.IntField(null=False, default=0, description="剩余秒数: [延迟生效时记录剩余秒数]")
    renew_time = fields.IntField(null=False, default=0, description="续费时间")
    effect_time = fields.IntField(null=False, default=0, description="生效时间")
    expire_time = fields.IntField(null=False, default=0, description="到期时间")
    create_time = fields.IntField(null=False, default=0, description="创建时间")
    update_time = fields.IntField(null=False, default=0, description="更新时间")
    delete_time = fields.IntField(null=False, default=0, description="删除时间")

    class Meta:
        table_description = "用户订阅表"
        table = DbModel.table_prefix("user_subscribe")


class UserWalletModel(DbModel):
    id = fields.IntField(pk=True, unsigned=True, description="主键")
    admin_id = fields.IntField(null=False, default=0, description="管理ID")
    user_id = fields.IntField(null=False, default=0, description="用户ID")
    log_sn = fields.CharField(null=False, max_length=64, default="", description="日志编号")
    scene = fields.CharField(null=False, max_length=20, default=0, description="场景: [points,train,robot,know,other]")
    action = fields.IntField(null=False, default=0, description="变动类型: [1=增加， 2=减少]")
    project = fields.CharField(null=False, max_length=100, default="", description="项目名称")
    source_sn = fields.CharField(null=False, max_length=64, default="", description="来源单号")
    source_id = fields.IntField(null=False, default=0, description="来源主键")
    change_type = fields.IntField(null=False, default=0, description="变动类型")
    change_amount = fields.IntField(null=False, default=0, description="变动的数量")
    before_amount = fields.IntField(null=False, default=0, description="变动前数量")
    after_amount = fields.IntField(null=False, default=0, description="变动后数量")
    remarks = fields.CharField(null=False, max_length=200, default="", description="备注")
    additional = fields.TextField(description="附加信息")
    create_time = fields.IntField(null=False, default=0, description="创建时间")

    class Meta:
        table_description = "用户余额表"
        table = DbModel.table_prefix("user_wallet")

    @classmethod
    async def inc(cls, scene: str, user_id: int, change_type: int, change_amount: int, **kwargs):
        user = await UserModel.filter(id=user_id).first()
        left_amount = 0
        if scene == WalletEnum.POINTS:
            left_amount = user.points
        elif scene == WalletEnum.TRAIN:
            left_amount = user.train_num
        elif scene == WalletEnum.ROBOT:
            left_amount = user.robot_num
        elif scene == WalletEnum.KNOW:
            left_amount = user.know_num

        await cls.create(
            action=1,
            scene=scene,
            log_sn=await ToolsUtil.make_order_sn(cls, "log_sn"),
            admin_id=kwargs.get("admin_id", 0),
            user_id=user_id,
            change_type=change_type,
            source_id=kwargs.get("source_id", 0),
            source_sn=kwargs.get("source_sn", ""),
            project=kwargs.get("project", ""),
            change_amount=change_amount,
            before_amount=max(left_amount - change_amount, 0),
            after_amount=left_amount,
            remarks=kwargs.get("remarks", ""),
            additional=kwargs.get("additional", ""),
            create_time=int(time.time())
        )

    @classmethod
    async def dec(cls, scene: str, user_id: int, change_type: int, change_amount: int, **kwargs):
        left_amount = 0
        user = await UserModel.filter(id=user_id).first()
        if scene == WalletEnum.POINTS:
            left_amount = user.points
        elif scene == WalletEnum.TRAIN:
            left_amount = user.train_num
        elif scene == WalletEnum.ROBOT:
            left_amount = user.robot_num
        elif scene == WalletEnum.KNOW:
            left_amount = user.know_num

        await cls.create(
            action=2,
            scene=scene,
            log_sn=await ToolsUtil.make_order_sn(cls, "log_sn"),
            admin_id=kwargs.get("admin_id", 0),
            user_id=user_id,
            change_type=change_type,
            source_id=kwargs.get("source_id", 0),
            source_sn=kwargs.get("source_sn", ""),
            project=kwargs.get("project", ""),
            change_amount=change_amount,
            before_amount=left_amount + change_amount,
            after_amount=left_amount,
            remarks=kwargs.get("remarks", ""),
            additional=kwargs.get("additional", ""),
            create_time=int(time.time())
        )


class UserVisitorModel(DbModel):
    id = fields.IntField(pk=True, unsigned=True, description="主键")
    user_id = fields.IntField(null=False, default=0, description="用户ID")
    terminal = fields.SmallIntField(null=False, default=0, description="客户端")
    summary = fields.CharField(null=False, max_length=100, default="", description="摘要信息")
    endpoint = fields.CharField(null=False, max_length=300, default="", description="请求函数")
    method = fields.CharField(null=False, max_length=30, default="", description="请求方法: [GET,POST]")
    url = fields.CharField(null=False, max_length=100, default="", description="请求路由")
    ip = fields.CharField(null=False, max_length=100, default="", description="请求IP")
    ua = fields.CharField(null=False, max_length=100, default="", description="请求UA")
    user_agent = fields.CharField(null=False, max_length=900, default="", description="UA详情")
    params = fields.TextField(default="", description="请求参数")
    error = fields.TextField(default="", description="错误信息")
    status = fields.SmallIntField(null=False, default=1, description="执行状态: [1=成功, 2=失败]")
    start_time = fields.CharField(null=False, default="0", max_length=20, description="开始时间: 毫秒")
    end_time = fields.CharField(null=False, default="0", max_length=20, description="结束时间: 毫秒")
    task_time = fields.CharField(null=False, default="0", max_length=20, description="耗时时间: 毫秒")
    create_time = fields.IntField(null=False, default=0, description="操作时间")

    class Meta:
        table_description = "用户浏览表"
        table = DbModel.table_prefix("user_visitor")
